package main;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class Propriedades {

	private static final String INFINITO = "infinito";

	private static final String NOME_ARQUIVO_PROPERTIES = "simulation.properties";

	private static final String TAG_GAMA = "gama";

	private static final String TAG_LAMBDA = "lambda";

	private static final String TAG_MI = "mi";

	private static final String TAG_U = "u";

	private static final String TAG_POPULACAO_INICIAL = "populacao-inicial";

	private static final String TAG_ARQUIVO_DEBUG = "debug";
	
	private static final String TAG_DEBUG_CONSOLE = "debug-console";

	private static final String TAG_ARQUIVO = "arquivo";

	private static final String TAG_BLOCOS = "blocos";
	
	private static final String TAG_BLOCOS_INICIAIS_SISTEMA = "blocos-iniciais-sistema";

	private static final String TAG_RECOMENDACAO = "recomendacao";

	private final static String TAG_SIMULACAO = "simulacao";
	
	private static final String TAG_TOTAL_VERIFICACOES = "total-verificacoes";
	
	private static final String TAG_INCLINACAO_MINIMA = "inclinacao-minima";
	
	private static final String TAG_METRICA = "metrica";
	
	private static final String TAG_FASE_TRANSIENTE = "fase-transiente";
	
	private final static String TAG_COLETAS_POR_RODADA = "coletas-por-rodada";
	
	private final static String TAG_RODADA = "rodada";
	
	private final static String POLITICA_VIZINHOS = "politica-selecao-vizinhos";
	
	private final static String POLITICA_BLOCOS = "politica-selecao-blocos";
	
	private static final String TAG_GRAFICOS = "graficos";

	private static final String TAG_GRAFICOS_PLOTAR = "plotar-graficos";
	
	private static final String TAG_GRAFICOS_NOME = "nome";
	
	private static final String TAG_GRAFICOS_DIRETORIO = "diretorio";
	
	private static final String TAG_GRAFICOS_ALTURA = "altura";
	
	private static final String TAG_GRAFICOS_LARGURA = "largura";
	
	private static final String TAG_ARQUIVO_VAZAO = "arquivo-vazao";
	
	private String nomeArquivo;
	private String nomeArquivoDebug;
	private boolean debugConsole;
	
	private String metrica;
	private double totalVerificacoes;
	private double inclinacaoMinima;
	
	private int coletasPorRodada;
	
	private Integer blocos;
	private Integer blocosIniciaisSistema;
	private Integer populacaoInicial;
	
	private Double p;
	
	private Double u;
	private Double mi;
	private Double lambda;
	private Double gama;
	
	private String politicaVizinhos;
	private String politicaBlocos;
	
	private boolean plotarGraficos;
	private String diretorioGraficos;
	private String nomeGraficos;
	private int larguraGraficos;
	private int alturaGraficos;

	private String arquivoVazao;
		
	public Propriedades() {
		File file = new File(NOME_ARQUIVO_PROPERTIES);
		
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = null;
		Document doc = null;
		
		try {
			db = dbf.newDocumentBuilder();
			doc = db.parse(file);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		doc.getDocumentElement().normalize();
		
		Element element = (Element) doc.getElementsByTagName(TAG_SIMULACAO).item(0);
		
		arquivoVazao = element.getAttribute(TAG_ARQUIVO_VAZAO);
		nomeArquivo = element.getAttribute(TAG_ARQUIVO);
		nomeArquivoDebug = element.getAttribute(TAG_ARQUIVO_DEBUG);
		String ativaDebugConsole = element.getAttribute(TAG_DEBUG_CONSOLE);
		if (ativaDebugConsole.equalsIgnoreCase("sim")) {
			debugConsole = true;
		}
		else {
			debugConsole = false;
		}
		
		Element elementFaseTransiente = (Element) element.getElementsByTagName(TAG_FASE_TRANSIENTE).item(0);
		metrica = elementFaseTransiente.getElementsByTagName(TAG_METRICA).item(0).getTextContent();
		totalVerificacoes = Double.valueOf(elementFaseTransiente.getElementsByTagName(TAG_TOTAL_VERIFICACOES).item(0).getTextContent());
		inclinacaoMinima = Math.abs(Double.valueOf(elementFaseTransiente.getElementsByTagName(TAG_INCLINACAO_MINIMA).item(0).getTextContent()));
		
		Element elementRodada = (Element) element.getElementsByTagName(TAG_RODADA).item(0);
		coletasPorRodada = Integer.valueOf(elementRodada.getElementsByTagName(TAG_COLETAS_POR_RODADA).item(0).getTextContent());
		
		Element elementBloco = (Element) element.getElementsByTagName(TAG_BLOCOS).item(0);
		blocos = Integer.valueOf(elementBloco.getTextContent());
		
		String blocosIniciaisSistemaRaw = elementBloco.getAttribute(TAG_BLOCOS_INICIAIS_SISTEMA);
		if (blocosIniciaisSistemaRaw.isEmpty()) {
			blocosIniciaisSistema = null;
		}
		else {			
			blocosIniciaisSistema = Integer.valueOf(blocosIniciaisSistemaRaw);
		}
		
		populacaoInicial = Integer.valueOf(element.getElementsByTagName(TAG_POPULACAO_INICIAL).item(0).getTextContent());
		
		p = Double.valueOf(element.getElementsByTagName(TAG_RECOMENDACAO).item(0).getTextContent());
		
		u = Double.valueOf(element.getElementsByTagName(TAG_U).item(0).getTextContent());
		mi = Double.valueOf(element.getElementsByTagName(TAG_MI).item(0).getTextContent());
		lambda = Double.valueOf(element.getElementsByTagName(TAG_LAMBDA).item(0).getTextContent());
		String valorGama = element.getElementsByTagName(TAG_GAMA).item(0).getTextContent();
		if (valorGama.equalsIgnoreCase(INFINITO)) {
			gama = -1.0;
		}
		else {
			gama = Double.valueOf(valorGama);
		}
		
		politicaVizinhos = element.getElementsByTagName(POLITICA_VIZINHOS).item(0).getTextContent();
		politicaBlocos = element.getElementsByTagName(POLITICA_BLOCOS).item(0).getTextContent();
		
		Element elementGrafico = (Element) element.getElementsByTagName(TAG_GRAFICOS).item(0);
		nomeGraficos = elementGrafico.getElementsByTagName(TAG_GRAFICOS_NOME).item(0).getTextContent();
		diretorioGraficos = elementGrafico.getElementsByTagName(TAG_GRAFICOS_DIRETORIO).item(0).getTextContent();
		String graficos = elementGrafico.getElementsByTagName(TAG_GRAFICOS_PLOTAR).item(0).getTextContent();
		if (graficos.equalsIgnoreCase("sim")) {
			plotarGraficos = true;
		}
		else {
			plotarGraficos = false;
		}
		
		Element elementLargura = (Element) elementGrafico.getElementsByTagName(TAG_GRAFICOS_LARGURA).item(0);
		if (elementLargura == null) {
			larguraGraficos = 800;
		}
		else {
			larguraGraficos = Integer.parseInt(elementLargura.getTextContent());
		}
		
		Element elementAltura = (Element) elementGrafico.getElementsByTagName(TAG_GRAFICOS_ALTURA).item(0);
		if (elementAltura == null) {
			alturaGraficos = 600;
		}
		else {
			alturaGraficos = Integer.parseInt(elementAltura.getTextContent());
		}
	}

	public String getNomeArquivo() {
		return nomeArquivo == null ? "" : nomeArquivo;
	}
	
	public String getNomeArquivoDebug() {
		return nomeArquivoDebug == null ? "" : nomeArquivoDebug;
	}
	
	public boolean getDebugConsole() {
		return debugConsole;
	}

	public Integer getBlocos() {
		return blocos == null ? 0 : blocos;
	}
	
	public Integer getBlocosIniciaisSistema() {
		return blocosIniciaisSistema == null ? 0 : blocosIniciaisSistema;
	}

	public Integer getPopulacaoInicial() {
		return populacaoInicial == null ? 0 : populacaoInicial;
	}

	public Double getP() {
		return p == null ? 0 : p;
	}

	public Double getU() {
		return u == null ? 0 : u;
	}

	public Double getMi() {
		return mi == null ? 0 : mi;
	}

	public Double getLambda() {
		return lambda == null ? 0 : lambda;
	}

	public Double getGama() {
		return gama == null ? 0 : gama;
	}
	
	public String getPoliticaVizinhos() {
		return politicaVizinhos;
	}
	
	public String getPoliticaBlocos() {
		return politicaBlocos;
	}

	public boolean getPlotarGraficos() {
		return plotarGraficos;
	}
	
	public String getMetrica() {
		return metrica;
	}

	public double getTotalVerificacoes() {
		return totalVerificacoes;
	}

	public double getInclinacaoMinima() {
		return inclinacaoMinima;
	}

	public int getColetasPorRodada() {
		return coletasPorRodada;
	}

	public String getDiretorioGraficos() {
		return diretorioGraficos;
	}

	public String getNomeGraficos() {
		return nomeGraficos;
	}

	public int getLarguraGraficos() {
		return larguraGraficos;
	}

	public int getAlturaGraficos() {
		return alturaGraficos;
	}

	public String getArquivoVazao() {
		return arquivoVazao;
	}
}
